package com.youyun56.gps.android;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import android.content.Context;
import android.net.ConnectivityManager;
import android.telephony.TelephonyManager;
import android.telephony.cdma.CdmaCellLocation;
import android.telephony.gsm.GsmCellLocation;
import android.util.Log;

import com.youyun56.gps.android.common.CommandFactory;
import com.youyun56.gps.android.common.Location;
import com.youyun56.gps.android.http.HttpManager;
import com.youyun56.gps.android.service.LocationUploadService;

public enum GpsFactory {
    factory;
    private long                     uploadInterval = 60 * 20;
    private ScheduledExecutorService uploadService;
    private ScheduledFuture<?>       uploadFuture;
    private final static String      tag            = GpsFactory.class.getName();
    private Location                 location;
    private Boolean                  run            = true;
    
    private GpsFactory() {
    }
    
    public Boolean start(Long uploadInterval) {
        run = true;
        Log.i(tag, "start gps");
        if (uploadInterval != null) {
            this.uploadInterval = uploadInterval;
        }
        uploadService = Executors.newScheduledThreadPool(1);
        uploadFuture = uploadService.scheduleAtFixedRate(uploadPositon, 1, this.uploadInterval, TimeUnit.SECONDS);
        return true;
    }
    
    public void stop() {
    }
    
    private Runnable uploadPositon = new Runnable() {
                                       
                                       @Override
                                       public void run() {
                                           try {
                                               Log.i(tag, "upload Position");
                                               // if (!isNetEnable()) {
                                               // enableNetWork(true);
                                               // }
                                               new Thread(new CdmaLocationClaimer()).start();
                                               waitLocationUnterminate();
                                               HttpManager.getInstance().excutePost(CommandFactory.uploadLocation(location, LocationUploadService.getInstance().getCar().getId()), null);
                                               location = null;
                                               stop();
                                           } catch (Exception e) {
                                               // TODO: handle exception
                                           }
                                       }
                                       
                                       private void waitLocationUnterminate() {
                                           while (location == null && run) {
                                               try {
                                                   Log.i(tag, "wait location");
                                                   Thread.sleep(3000);
                                               } catch (InterruptedException e) {
                                                   Log.e(tag, e.getMessage(), e);
                                               }
                                           }
                                       }
                                   };
    
    private Boolean isNetEnable() {
        TelephonyManager telephonyManager = (TelephonyManager) LocationUploadService.getInstance().getSystemService(Context.TELEPHONY_SERVICE);
        if (telephonyManager.getDataState() == TelephonyManager.DATA_CONNECTED) {
            return true;
        } else {
            return false;
        }
    }
    
    private static Boolean enableNetWork(Boolean enabled) {
        try {
            final ConnectivityManager conman = (ConnectivityManager) LocationUploadService.getInstance().getSystemService(Context.CONNECTIVITY_SERVICE);
            final Class<?> conmanClass = Class.forName(conman.getClass().getName());
            final Field iConnectivityManagerField = conmanClass.getDeclaredField("mService");
            iConnectivityManagerField.setAccessible(true);
            final Object iConnectivityManager = iConnectivityManagerField.get(conman);
            final Class<?> iConnectivityManagerClass = Class.forName(iConnectivityManager.getClass().getName());
            final Method setMobileDataEnabledMethod = iConnectivityManagerClass.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE);
            setMobileDataEnabledMethod.setAccessible(true);
            setMobileDataEnabledMethod.invoke(iConnectivityManager, enabled);
            return true;
        } catch (Exception e) {
            Log.e(tag, e.getMessage(), e);
            return false;
        }
    }
    
    class CdmaLocationClaimer implements Runnable {
        
        @Override
        public void run() {
            TelephonyManager telephonyManager = (TelephonyManager) LocationUploadService.getInstance().getSystemService(Context.TELEPHONY_SERVICE);
            if (telephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) {
                GsmCellLocation cellLocation = (GsmCellLocation) telephonyManager.getCellLocation();
                if (cellLocation != null) {
                    
                } else {
                    Log.e(tag, "no GsmCellLocation");
                }
            } else if (telephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
                CdmaCellLocation cdma = (CdmaCellLocation) telephonyManager.getCellLocation();
                if (cdma != null) {
                    double lat = (double) cdma.getBaseStationLatitude() / 14400;
                    double lon = (double) cdma.getBaseStationLongitude() / 14400;
                    location = new Location(lat, lon);
                    // if (lat < 360 && lon < 360) {
                    // }
                } else {
                    Log.e(tag, "can get cdma cell location");
                }
            } else {
                Log.e(tag, "no suitable PHONE_TYPE");
            }
        }
        
    }
    
    public void shutdown() {
        run = false;
        if (uploadService != null) {
            uploadService.shutdownNow();
        }
    }
    
}
